#ifndef EGADU_H
#define EGADU_H

#include "eGadu_dec.h"
#include "eGaduList.h"
#include <Windows.h>

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

/**
    @brief Przestrzeń nazw biblioteki eGadu
*/
namespace eGaduLib
{
    /// @brief Typ zdarzeń connected oraz disconnected
	typedef void (*Event)();

	/**
	@brief Typ zdarzenia listUpdateEvent
	@param [out] list Wskaźnik do listy kontaktów
	@param [out] updatedUin Zaktualizowany numer na liście kontaktów
	*/
	typedef void (*ListUpdateEvent)(eGaduList *list, int updatedUin);

	/**
    @brief Typ zdarzenia newMessageEvent
    @param [out] from Numer nadawcy
    @param [out] plainMsg Wskaźnik do czystego tekstu wiadomości
    @param [out] htmlMsg Wskaźnik do tekstu sformatowanego HTML
    @todo Czas nadania wiadomości
	*/
	typedef void (*NewMessageEvent)(int from, char *plainMsg, char *htmlMsg);


    /**
    @brief Główna klasa biblioteki

	Odpowiedzialna za wszystkie operacje protokołu Gadu-Gadu.
	@note Ta klasa jest ciągle rozbudowywana.
	*/
	class DLL_EXPORT eGadu
	{
	public:
		/// Konstruktor
		eGadu(void);
		/// Desktruktor
		~eGadu(void);

		/**
		@brief Logowanie
		@param [in] num Numer Gadu-Gadu
		@param [in] password Hasło Gadu-Gadu
		@param [in] status Początkowy status
		@param [in] description Opis (nie musi wystąpić)
		@return Zobacz ::EGADU_RETURN
		*/
		EGADU_RET login(int num, char *password, int status, const char *description = 0);

        /**
        @brief Uruchomienie pętli odbierania pakietów
        @return Zobacz ::EGADU_RETURN
        */
		EGADU_RET startRecvLoop();

		/**
		@brief Zatrzymanie pętli odbierania pakietów
		@return Zobacz ::EGADU_RETURN
		*/
		EGADU_RET stopRecvLoop();

        /**
        @brief Analiza nagłówka pakietu

        Analizuje i odpowiednio przetwarza resztę pakietu
        @note Użytkownik nie powinien używać tej metody
        */
		void resolveHeader(gg_header hdr);

        /**
        @brief Wysyłanie wiadomości

        Wiadomość powinna być zakodowana w UTF-8
        @param [in] to Wskaźnik na kontakt, do którego wiadomość jest adresowana.
        @param [in] msg Treść wiadomości w postaci czystego tekstu
        @return Zobacz ::EGADU_RETURN
        @todo Możliwość wysyłania już sformatowanego tekstu HTML
        */
		EGADU_RET sendMessage(User *to, const char *msg);

        /**
        @brief Zamyka połączenie

        @note Przed rozłączeniem z serwerem, jeśli wcześniej było się zalogowanym, należy pamiętać o tym, aby zmienić status na niedostępny (lub niedostępny z opisem). W przecziwnym wypadku mogą wystąpić problemy z ponownym zalogowaniem się
        */
		void closeConnection();

        /**
        @brief Zmiana statusu
        @param [in] newStatus Nowy status, zobacz ::EGADU_STATUS
        @param [in] newDescription Nowy opis (nie musi wystąpić)
        @return Zobacz ::EGADU_RETURN
        */
		EGADU_RET changeStatus(EGADU_STATUS newStatus, const char *newDescription = 0);

		/**
		@brief Aktualizacja listy kontaktów na serwerze
		@param [in] list Wskaźnik do listy kontaktów (zobacz eGaduList)
		@return Zobacz ::EGADU_RETURN
		*/
		EGADU_RET updateContactsList(eGaduList *list);

        /**
        @brief Zdarzenie ::ListUpdateEvent

        Wywoływane po zaktualizowaniu listy kontaktów (zmiana statusu przez jakiś kontakt z listy)
        */
		ListUpdateEvent listUpdateEvent;

		/**
        @brief Zdarzenie ::Event

        Wywoływane po zalogowaniu do serwera
		*/
		Event connected;

		/**
		@brief Zdarzenie ::Event

		Wywoływane po wylogowaniu z serwera
		@note Wywołanie tego zdarzenia nie oznacza zerwania połączenia. Po wywołaniu tego zdarzenia, aby całkowicie się rozłączyć należy wywołać metodę eGadu::closeConnection
		*/
		Event disconnected;

		/**
		@brief Zdarzenie ::NewMessageEvent

		Wywoływane po otrzymaniu nowej wiadomości
		*/
		NewMessageEvent newMessageEvent;

    };
}

#endif


